//=======================================================================//
//= Include files.													    =//
//=======================================================================//
#include <wx/string.h>
#include <wx/textfile.h>
#include "InputTextCtrl.h"
#include "Settings.h"

//=======================================================================//
//= Data type define.                                                   =//
//=======================================================================//
DEFINE_LOCAL_EVENT_TYPE(wxEVT_TEXT_SEL);
wxIMPLEMENT_DYNAMIC_CLASS(TextSelectEvent, wxEvent);

//=======================================================================//
//= Function define.										            =//
//=======================================================================//

TextSelectEvent::TextSelectEvent(int iID, const wxString& clsText)
: wxEvent(iID, wxEVT_TEXT_SEL)
{
	m_strText = clsText;
	m_lSelectionStart = wxNOT_FOUND;
	m_lSelectionEnd = wxNOT_FOUND;
}

TextSelectEvent::TextSelectEvent(const TextSelectEvent& clsEvent)
: wxEvent(clsEvent)
{
	m_strText = clsEvent.GetText();
	m_lSelectionStart = clsEvent.GetSelectionStart();
	m_lSelectionEnd = clsEvent.GetSelectionEnd();
}


BEGIN_EVENT_TABLE(InputTextCtrl, wxTextCtrl)
//	EVT_LEFT_DOWN(InputTextCtrl::OnCaptureMouneDown)
//	EVT_LEFT_UP(InputTextCtrl::OnCaptureMouneUp)
//	EVT_MOUSE_CAPTURE_LOST(InputTextCtrl::OnMouseCaptureLost)
	EVT_IDLE(InputTextCtrl::OnIdle)
END_EVENT_TABLE()
InputTextCtrl::InputTextCtrl(wxWindow *pclsParent, wxWindowID iID)
: wxTextCtrl(pclsParent, iID, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE, wxDefaultValidator, wxT("Input Text"))
{
	SetMinSize(wxSize(800, 200));
}

InputTextCtrl::~InputTextCtrl(void)
{

}

bool InputTextCtrl::_judgeSelection(void)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	static long			s_lPreviousSelectionStart = wxNOT_FOUND;
	static long			s_lPreviousSelectionEnd = wxNOT_FOUND;
	long				lSelectionStart;
	long				lSelectionEnd;
	bool				bSelectionChanged;

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	/* Get now selection. */
	wxTextCtrl::GetSelection(&lSelectionStart, &lSelectionEnd);

	/* Jusge selection changed. */
	if((s_lPreviousSelectionStart != lSelectionStart) || (s_lPreviousSelectionEnd != lSelectionEnd))
	{
		bSelectionChanged = true;
	}
	else
	{
		bSelectionChanged = false;
	}
	s_lPreviousSelectionStart = lSelectionStart;
	s_lPreviousSelectionEnd = lSelectionEnd;

	return bSelectionChanged;
}

void InputTextCtrl::OnCaptureMouneDown(wxMouseEvent& clsEvent)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	wxPostEvent(GetParent(), clsEvent);
	// Capture all mouse event in this control, even if out of the control range.
	CaptureMouse();
	clsEvent.Skip();
}

void InputTextCtrl::OnCaptureMouneUp(wxMouseEvent& clsEvent)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	wxString			strSelectedText = wxTextCtrl::GetStringSelection();

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	if(clsEvent.LeftUp())
	{
		TextSelectEvent clsSelectEvent(wxTextCtrl::GetId(), strSelectedText);
		wxPostEvent(wxTextCtrl::GetParent(), clsSelectEvent);
	}
	// Release mouse event from this control.
	//ReleaseMouse();
	clsEvent.Skip();
}

void InputTextCtrl::OnMouseCaptureLost(wxMouseCaptureLostEvent& clsEvent)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	ReleaseMouse();
	clsEvent.Skip();
}

void InputTextCtrl::OnIdle(wxIdleEvent& clsEvent)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	if(_judgeSelection())
	{
		TextSelectEvent clsSelectEvent(wxTextCtrl::GetId());
		long			lSelectionStart;
		long			lSelectionEnd;
		/* Get now selection. */
		wxTextCtrl::GetSelection(&lSelectionStart, &lSelectionEnd);

		clsSelectEvent.SetText(wxTextCtrl::GetStringSelection());
		clsSelectEvent.SetSelectionStart(lSelectionStart);
		clsSelectEvent.SetSelectionEnd(lSelectionEnd);

		wxPostEvent(wxTextCtrl::GetParent(), clsSelectEvent);
	}

	clsEvent.Skip();
}

void InputTextCtrl::Clear(void)
{
	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	wxTextCtrl::Clear();
}

bool InputTextCtrl::OpenFile(const wxString& cstrFilePath)
{
	/*----------------------------------*/
	/* Variable Declaration				*/
	/*----------------------------------*/
	wxTextFile			clsInputFile;
	bool				bReturn;
	wxString			strTextContent;

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
	bReturn = clsInputFile.Open(cstrFilePath, wxConvAuto(wxFONTENCODING_UTF8));
	if(true == bReturn)
	{
		/* Cleanup now content. */
		wxTextCtrl::Clear();
		/* Read first line. */
		strTextContent.Append(clsInputFile.GetFirstLine());
		strTextContent.Append('\n');
		for(size_t sLineIdx=1; sLineIdx<clsInputFile.GetLineCount(); sLineIdx++)
		{
			strTextContent.Append(clsInputFile.GetNextLine());
			strTextContent.Append(wxT('\n'));
		}
		wxTextCtrl::SetValue(strTextContent);

    }
	return bReturn;
}
